struct Vertex
{
	float4 f4Pos	: POSITION0;
	float2 f2Coord	: TEXCOORD0;
	float3 f3Norm	: TEXCOORD1;
	float3 f3Pos	: TEXCOORD2;
};

struct PointLight
{
	float3 f3Color;
	float3 f3Pos;
	float3 f3Atte;
};

struct DirectLight
{
	float3 f3Color;
	float3 f3Dir;
};

uniform extern float4x4 mTrans;
uniform extern float4x4 mPos;
uniform extern float4x4 mNorm;

uniform extern float fRef;

uniform extern float3 f3View;

uniform extern texture tex;
uniform extern float4 f4Mate;

PointLight pl;
DirectLight dl;

float4 Track(float3 f3Pos: POSITION0) : POSITION0
{
	return mul(float4(f3Pos,1.0f),mTrans);
}

float4 Refer(): COLOR0
{
	return float4(fRef,0.0f,0.0f,0.0f);
}

Vertex Trans(
	float3 f3Pos: POSITION0,
	float3 f3Norm: NORMAL0,
	float2 f2Coord: TEXCOORD0
)
{
	Vertex vout = (Vertex)0;
	vout.f4Pos = mul(float4(f3Pos,1.0f),mTrans);
	vout.f2Coord = f2Coord;
	vout.f3Norm = mul(float4(f3Norm,0.0f),mNorm).xyz;
	vout.f3Pos = mul(float4(f3Pos,1.0f),mPos).xyz;
	return vout;
}

sampler smpl = sampler_state
{
	Texture = <tex>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
};

float3 Ambient(float3 f3Lit, float3 f3Mate)
{
	return f3Lit*f3Mate;
}

float3 Diffuse(float3 f3Lit, float3 f3Mate, float3 f3Vec, float3 f3Norm)
{
	return f3Lit*f3Mate*max(dot(f3Vec,f3Norm),0.0f);
}

float3 Specular(float3 f3Lit, float fMate, float fPow, float3 f3Vec, float3 f3Norm, float3 f3Pos)
{
	return f3Lit*fMate*pow(max(dot(reflect(-f3Vec,f3Norm),normalize(f3View-f3Pos)),0.0f),fPow);
}

float4 Point(
	float2 f2Coord: TEXCOORD0,
	float3 f3Norm: TEXCOORD1,
	float3 f3Pos: TEXCOORD2
): COLOR0
{
	float3 f3Color = tex2D(smpl,f2Coord).rgb;
	float3 f3Vec = pl.f3Pos-f3Pos;
	float3 f3UniVec = normalize(f3Vec);
	float3 f3UniNorm = normalize(f3Norm);
	float fDist2 = dot(f3Vec,f3Vec)*1.0f;
	return float4(
		1.0f/(pl.f3Atte.x+pl.f3Atte.y*sqrt(fDist2)+pl.f3Atte.z*fDist2)*(
			Ambient(pl.f3Color,f3Color*f4Mate.x)+
			Diffuse(pl.f3Color,f3Color*f4Mate.y,f3UniVec,f3UniNorm)+
			Specular(pl.f3Color,f4Mate.z,f4Mate.w,f3UniVec,f3UniNorm,f3Pos)
		),
		1.0f
	);
}

float4 Direct(
	float2 f2Tex: TEXCOORD0,
	float3 f3Norm: TEXCOORD1,
	float3 f3Pos: TEXCOORD2
): COLOR0
{
	float3 f3Color = tex2D(smpl,f2Tex).rgb;
	float3 f3UniVec = normalize(dl.f3Dir);
	float3 f3UniNorm = normalize(f3Norm);
	return float4(
		Ambient(dl.f3Color,f3Color*f4Mate.x)+
		Diffuse(dl.f3Color,f3Color*f4Mate.y,f3UniVec,f3UniNorm)+
		Specular(dl.f3Color,f4Mate.z,f4Mate.w,f3UniVec,f3UniNorm,f3Pos),
		1.0f
	);
}

technique MultiLightPass
{
	pass _0
	{
		vertexShader = compile vs_2_0 Track();
		pixelShader  = compile ps_2_0 Refer();
	}
	pass _1
	{
		vertexShader = compile vs_2_0 Trans();
		pixelShader  = compile ps_2_0 Direct();
	}
	pass _2
	{
		vertexShader = compile vs_2_0 Trans();
		pixelShader  = compile ps_2_0 Point();
	}
}
